<template>
  <DetailPanner :show="show">
    <template #left>
      <div class="user">
        <span class="user_name">
          {{ selectSession?.msgCustomType === 1 ? selectSession?.groupName : selectSession?.nickName }}
        </span>
      </div>
    </template>
    <template #right>
      <div class="mode noDrag" :class="stopClick ? 'stopClick' : null">
        <div v-for="item in 1" @click="watchCurrentInfo($event)">
        </div>
        <span></span>
      </div>
    </template>
    <template #main>
      <div class="msgMain noDrag" :class="stopClick ? 'stopClick' : null">
        <el-scrollbar class="msg_list" ref="msgbox" :min-size="10" @scroll="scroll">
          <MessageItem @openUser="openUser" :row="row" v-for="row in message" v-model="chckedList">
            <div class="msgInfos" @click.right="openUserAction($event, row)" :key="row.msgId">
              <MessageText ref="textRef" v-if='(row?.msgType == "TEXT" || row?.msgType === "IMAGE")' :row="row" />
            </div>
            <Notice v-if="(row?.msgType === 'ALERT' || row?.msgType === 'REVOKE')" :row="row" />
            <GroupChat v-if="(row?.msgType === 'CARD')" :row="row" />
          </MessageItem>

        </el-scrollbar>
        <MessageSend v-model:showQuote="showQuote" :row="row" ref="messageSendRef"
          :seleteUserCardInfo="seleteUserCardInfo" />
        <section class="forward" v-if="openChecked">
          <div @click="forwardAction">
            <img src="local-media://icon_repost.png" alt="">
            <span class="text">转发</span>
          </div>
          <div @click="deleteMsg(false)">
            <img src="local-media://icon_delete.png" alt="">
            <span class="text">删除</span>
          </div>
          <i class="close" @click="changeChecked(false)">
            <el-icon>
              <Close />
            </el-icon>
          </i>
        </section>

        <el-popover :popper-options="{
          modifiers: [
            {
              name: 'computeStyles',
              options: {
                adaptive: false,
                enabled: false,
              },
            },
          ],
        }" popper-class="popperUserAction" width="100" v-model:visible="actionVisible" placement="bottom-start"
          trigger="foucs" virtual-triggering :virtual-ref="triggerUserActionRef" :teleported="false" :show-arrow="false">
          <section class="msgAction" @click="(actionVisible = false)">
            <span @click="copy" v-if="seleteUserCardInfo?.msgType === 'TEXT'">复制</span>
            <span @click="fastForwarding(seleteUserCardInfo)">转发</span>
            <span
              v-if="(seleteUserCardInfo?.userId === userInfo?.userId && (new Date().getTime() - seleteUserCardInfo.timestamp) < (1000 * 60 * 3))"
              @click="withdraw">撤回</span>
            <span @click="deleteMsg(true)">删除</span>
            <span @click="changeChecked(true)">多选</span>
            <span @click="showQuote = true">引用</span>
          </section>
        </el-popover>

        <el-popover width="270" v-model:visible="visible" placement="bottom-start" trigger="click" virtual-triggering
          :virtual-ref="triggerRef" :teleported="false" :show-arrow="false">
          <FriendDetail @submit="addFriend" :showButton="showActionButton" v-if="selectUserInfo?.userId"
            :userId="selectUserInfo?.userId" sm />
          <GroupDetail :showButton="showActionButton" sm :groupId="selectUserInfo?.groupId"
            v-if="selectUserInfo?.groupId" />
        </el-popover>
      </div>
    </template>
  </DetailPanner>
</template>
<script setup>
import DetailPanner from '@/components/DetailPanner.vue';
import { computed, watch, nextTick, ref, defineProps } from 'vue';
import MessageItem from './MessageItem'
import MessageSend from './MessageSend'
import MessageText from './MessageItem/MessageText'
import MessageVoice from './MessageItem/MessageVoice'
import Notice from './MessageItem/Notice'
import GroupChat from './MessageItem/GroupChat'
import { db } from "@/config/data";
import { useStore } from 'vuex';
import { sendMessage, sendGroupMessage, addFriendAction } from '@/server/friend'
import { ClickOutside as vClickOutside } from 'element-plus'
import { useDebounceFn, useRequest } from 'vue-hooks-plus'
import FriendDetail from '@/views/Friend/FriendPanner/FriendDetail'
import useLiveQuery from '@/tool/useLiveQuery'
import GroupDetail from '@/views/Friend/FriendPanner/GroupDetail'
import { ElMessage } from 'element-plus'
import { groupState } from '@/tool'
const props = defineProps({
  row: {
    type: Object,
    default: () => ({})
  },
  currentDetail: {
    type: Object,
    default: () => ({})
  },
  show: {
    type: Boolean,
    default: () => false
  }
})
const pageSize = ref(15)
const loadMore = ref(false)
const store = useStore()
const userInfo = computed(() => store.state.userInfo)
const selectSession = computed(() => store.state.selectSession)
const msgbox = ref()
const scrollToBottom = async () => {
  const height = msgbox.value?.wrapRef.scrollHeight
  await nextTick()
  msgbox.value.setScrollTop(height)
}
const search = computed(() => ({ uuid: props?.row?.uuid }))
const privateChat = useLiveQuery(() => db.privateChat?.where(search.value).reverse()?.limit(pageSize.value).toArray() || [], [pageSize])
const privateMsg = computed(() => [...(privateChat?.value || [])]?.reverse())
const groupChat = useLiveQuery(() => db.groupChat?.where(search.value).reverse()?.limit(pageSize.value).toArray() || [], [pageSize])
const groupMsg = computed(() => [...(groupChat?.value || [])]?.reverse())
const message = computed(() => [...(privateMsg.value || []), ...(groupMsg.value || [])])
const chckedList = computed(() => store.state.selectMessages)
const groupInfoData = useLiveQuery(() => db.groupInfo.get(search.value), [search])
const stopClick = computed(() => {
  const alertSubdivideType = groupInfoData.value?.alertSubdivideType
  const result = Reflect.get(groupState, alertSubdivideType)
  return result
})
watch(() => message.value?.length, async (value, oladValue) => {

  if (value === oladValue) return //数量没有变化,加载完毕
  await nextTick()
  if (selectSession.value.uuid === props?.row?.uuid && props.show) {
    await db.conversation.update(props?.row?.id, { hasRead: 0 })
    if (!loadMore.value) scrollToBottom()
  }
})


watch(() => props.show, async (newValue) => {

  if (!newValue) {
    pageSize.value = 15 //每次切换页面,回到最开始的
  }
  scrollToBottom()
})


const openChecked = computed(() => store.state.openChecked)

watch(openChecked, () => {
  store.commit('saveSelectMessages', [])
})


const messageSendRef = ref()
const seleteUserCardInfo = ref()
const actionVisible = ref(false)

const positionUserAction = ref({
  top: 0,
  left: 0,
  bottom: 0,
  right: 0
})
const triggerUserActionRef = ref({
  getBoundingClientRect: () => {
    return positionUserAction.value
  }
})

const openUserAction = (e, row) => {
  if (openChecked.value) return //已经开启了选择框,则不允许打开消息菜单栏
  seleteUserCardInfo.value = row
  positionUserAction.value = DOMRect.fromRect({
    width: 0,
    height: 0,
    x: e.clientX,
    y: e.clientY,
  })
  actionVisible.value = true
  e.preventDefault()
}

//复制
const copy = () => {
  let content = seleteUserCardInfo.value?.content
  try {
    const res = JSON.parse(content)
    if (res?.content) {
      content = res.content
    }
  } catch (error) {

  }
  messageSendRef.value?.editText(content)
}

//撤回
const withdraw = async () => {
  // 3分钟内的消息不允许撤回
  if ((new Date().getTime() - seleteUserCardInfo.timestamp) < (1000 * 60 * 3)) return
  const info = { ...seleteUserCardInfo.value }
  const isGroup = info?.msgCustomType === 1
  const params = {
    userId: selectSession.value?.userId,
    msgType: 'REVOKE',
    content: info.msgId,
    msgId: info.msgId,
  }
  const groupMsg = {
    groupId: selectSession.value?.groupId,
    msgType: 'REVOKE',
    content: info.msgId,
    msgId: info.msgId,
  }
  const res = isGroup ? await sendGroupMessage(groupMsg) : await sendMessage(params)
  if (res?.status === '0') {
    const editInfo = {
      content: '我撤回了一条信息',
      msgType: 'REVOKE',
      timestamp: new Date().getTime()
    }
    isGroup ? await db.groupChat.where({ msgId: info.msgId }).modify(editInfo) : await db.privateChat.where({ msgId: info.msgId }).modify(editInfo)
    await db.conversation.where({ uuid: info?.uuid }).modify({ ...editInfo, lastMsg: editInfo.content })
  }
}
const deleteMsg = async (deleteOne = true) => {
  const info = { ...seleteUserCardInfo.value }
  const isGroup = info.msgCustomType === 1
  const hasItem = await Reflect.get(db, isGroup ? 'groupChat' : "privateChat")?.get({ msgId: info?.msgId })
  if (hasItem) {
    if (deleteOne) {
      await Reflect.get(db, isGroup ? 'groupChat' : "privateChat").where({ msgId: info?.msgId }).delete() //删除
    } else {
      const deleteId = chckedList.value.map(r => r.msgId)
      await Reflect.get(db, isGroup ? 'groupChat' : "privateChat").where('msgId').anyOf(deleteId).delete()
    }
    const lastItem = await Reflect.get(db, isGroup ? 'groupChat' : "privateChat").where({ uuid: hasItem.uuid }).last() //查询最后一项
    await db.conversation.where({ uuid: hasItem.uuid }).modify({ hasRead: 0, lastMsg: lastItem?.content, timestamp: lastItem.timestamp })
  }
}

const forwardAction = () => {
  const waitMsg = store.state.selectMessages
  if (waitMsg.length === 0) return
  store.commit('saveSearchType', 3)
  store.commit('saveDialogState', true)

}

const fastForwarding = (v) => {
  store.commit('saveSelectMessages', [{ ...v }])
  store.commit('saveSearchType', 3)
  store.commit('saveDialogState', true)
}
const changeChecked = (state) => store.commit('saveOpenChecked', state)

const { run: scroll } = useDebounceFn(
  async (v) => {
    if (v.scrollTop < 200) {
      loadMore.value = true
      pageSize.value += 10
    }
    if (msgbox.value?.wrapRef.scrollHeight - msgbox.value?.wrapRef.scrollTop === msgbox.value?.wrapRef.clientHeight) {
      // 到底了
      loadMore.value = false
    }
  },
  {
    wait: 200,
  },
)

const visible = ref(false)
const position = ref({
  top: 0,
  left: 0,
  bottom: 0,
  right: 0
})
const selectUserInfo = ref()
const showActionButton = ref(true)
const triggerRef = ref({
  getBoundingClientRect: () => {
    return position.value
  }
})
const openUser = ({ data, p }) => {
  const state = { ...data }
  delete state?.groupId
  position.value = p
  selectUserInfo.value = state
  showActionButton.value = true
  visible.value = true
}

const showQuote = ref(false)
const watchCurrentInfo = (e) => {
  position.value = DOMRect.fromRect({
    width: 0,
    height: 0,
    x: e.clientX,
    y: e.clientY,
  })
  const isGroup = props.row?.msgCustomType === 1
  if (isGroup) {
    selectUserInfo.value = { groupId: props.row?.groupId }
  } else {
    selectUserInfo.value = { userId: props.row.userId }
  }
  showActionButton.value = false
  visible.value = true
}

const { runAsync: addFriendMethod } = useRequest(addFriendAction, {
  onSuccess: res => {
    ElMessage({
      type: 'success',
      message: "已发出申请",
      center: true,
    })
  },
  manual: true
})
const addFriend = async () => {
  const bands = await db.groupInfo.get({ uuid: selectUserInfo.value.uuid })
  if (bands?.friendEach === "Y") {
    //允许加好友
    await addFriendMethod({
      reason: '申请添加为好友',
      source: "3",
      userId: selectUserInfo.value?.userId
    })
  } else {
    ElMessage({
      type: 'warning',
      message: '已关闭群员互加好友,请联系管理员',
      center: true,
    })
  }
}
</script>

<style scoped lang="less">
.mode {
  display: flex;
  align-items: center;

  &.stopClick {
    pointer-events: none;
    cursor: not-allowed;
    user-select: none;
  }

  >span {
    width: 1px;
    height: 18px;
    opacity: 1;
    border: 1px solid #E1E1E1;
    margin: 0 12px;

  }

  >div {
    width: 26px;
    object-fit: cover;
    margin-left: 8px;
    height: 26px;
    background-size: 100% 100%;
    background-repeat: no-repeat;

    // &:first-child {
    //   background-image: url('~@/assets/icons/video.png');

    //   &:hover {
    //     background-image: url('~@/assets/icons/video_s.png');
    //   }
    // }

    // &:nth-child(2) {
    //   background-image: url('~@/assets/icons/phone.png');

    //   &:hover {
    //     background-image: url('~@/assets/icons/phone_s.png');
    //   }
    // }

    &:nth-child(1) {
      background-image: url('~@/assets/icons/dian.png');

      &:hover {
        background-image: url('~@/assets/icons/dian_s.png');
      }
    }
  }
}

.user {
  display: flex;
  align-items: center;
  padding-left: 12px;

  .user_name {
    font-size: 16px;

    font-weight: 500;
    color: #242424;
  }

  .user_state {
    font-size: 14px;

    font-weight: 400;
    color: #787878;
    margin-left: 12px;

  }
}

.msgMain {
  height: 100%;
  width: 100%;
  position: relative;

  &.stopClick {
    pointer-events: none;
    cursor: not-allowed;
    user-select: none;
  }


  :deep(.popover) {
    // width: 70px !important;
    min-width: 100px !important;
    padding: 5px 0;
    width: 100px !important;
  }

  .msg_list {
    padding: 0 20px;
    padding-top: 10px;
    height: calc(100% - 132px);
    // overflow-y: scroll;
    display: flex;
    flex-direction: column;
    width: 100%;
    box-sizing: border-box;
    position: relative;

    // &::-webkit-scrollbar {
    //   width: 5px;
    //   border-radius: 30px;
    // }

    // &::-webkit-scrollbar-thumb {
    //   height: 5px;
    //   width: 5px;
    //   background: rgba(161, 161, 161, 0.7);
    // }
  }
}

.msgAction {
  display: flex;
  flex-direction: column;
  width: 100%;

  >span {
    line-height: 22px;
    padding: 5px 16px;
    display: flex;
    align-items: center;
    width: 100%;
    justify-content: center;
    letter-spacing: 2px;
    cursor: pointer;
    white-space: nowrap;
    font-size: 14px;
    font-weight: bold;

    &:hover {
      color: var(--el-color-primary);
      background-color: #f7f7f7;
    }
  }
}

.forward {
  width: 100%;
  height: 132px;
  background: #FFFFFF;
  flex-shrink: 0;
  display: flex;
  position: absolute;
  left: 0;
  width: 100%;
  z-index: 1;
  bottom: 0;
  justify-content: center;
  align-items: center;

  >div {
    display: flex;
    align-items: center;
    flex-direction: column;
    margin-right: 10px;
    padding: 0 20px;
    cursor: pointer;

    .text {
      font-size: 14px;
    }
  }

  .close {
    position: absolute;
    right: 20px;
    top: 20px;
    font-size: 14px;
    cursor: pointer;
  }
}

.msgInfos {
  align-items: baseline;
  display: flex;
  justify-content: var(--showAlign);
  -webkit-app-region: no-drag;
}
</style>
<style>
.popperUserAction {
  width: 100px;
  min-width: 100px !important;
  padding: 10px 0 !important;
}
</style>
